package com.br.cashflowdao.hibernate.dao.factory;

import com.br.cashflowdao.hibernate.dao.*;
import com.br.cashflowdao.hibernate.dao.CreditTransactionDAO;

/**
 * This factory class creates and returns DAO for use in any
 * environment Hibernate has been configured for. Any DAO available through
 * a factory method should be declared in the superclass and implemented here.
 * If a implementation is not provided then the method should throw
 * an <code>UnsupportedOperationException</code>.
 * <p>
 * The line below shows the correct usage of this class and its methods.
 * First you must get a reference of MySqlDAOFactory in the following way:
 * <code>DAOFactory factory = DAOFactory.getInstance(MySqlDAOFactory.class);</code>
 * Then you can create any managed DAO that is registered in this factory in this fashion:
 * <code>//Returns a new instance MyDAO
 * MyDAO myDAO = factory.getMyDAO();</code>
 * Any methods inside this class act as a factory method, which means that 
 * every time the <code>getMyDAO()</code> method is invoked it creates a new instance
 * of MyDAO class.
 *<p>
 *
 * @author Marcel Sena <marcel.sena at marcel.sena@gmail.com>
 * @version 1.0
 * @since 05/01/2009
 */
public final class MySqlDAOFactory extends DAOFactory {

    /**
     * Factory method for instantiation of concrete DAO class
     * <p>
     *
     * @param <code>Class</code> that represents the factory that will be created
     * to manage all DAO factories.
     * @return a <code>DAOFactory</code> responsible to instantiate the DAOs.
     * @throws a <code>RuntimeException</code> if the factory can not be created.
     */
    private IDAO instantiateDAO(Class daoClass) {
        try {
            IDAO dao = (IDAO) daoClass.newInstance();
            return dao;
        } catch (Exception ex) {
            throw new RuntimeException("Can not instantiate DAO: " + daoClass, ex);
        }
    }

    /**
     * @see com.br.cashflowdao.hibernate.dao.factory.DAOFactory.getGenericDAO()
     */
    @Override
    public GenericDAO getGenericDAO() {
       return (GenericDAO) instantiateDAO(GenericDAO.class);
    }

    /**
     * @see com.br.cashflowdao.hibernate.dao.factory.DAOFactory.getAccountDAO()
     */
    @Override
    public AccountDAO getAccountDAO() {
         return (AccountDAO) instantiateDAO(AccountDAO.class);
    }

    /**
     * @see com.br.cashflowdao.hibernate.dao.factory.DAOFactory.getCategoryDAO()
     */
    @Override
    public CategoryDAO getCategoryDAO() {
       return (CategoryDAO) instantiateDAO(CategoryDAO.class);
    }

    /**
     * @see com.br.cashflowdao.hibernate.dao.factory.DAOFactory.getCreditTransactionDAO()
     */
    @Override
    public CreditTransactionDAO getCreditTransactionDAO() {
        return (CreditTransactionDAO) instantiateDAO(CreditTransactionDAO.class);
    }

    /**
     * @see com.br.cashflowdao.hibernate.dao.factory.DAOFactory.getDebitTransactionDAO()
     */
    @Override
    public DebitTransactionDAO getDebitTransactionDAO() {
       return (DebitTransactionDAO) instantiateDAO(DebitTransactionDAO.class);
    }

    /**
     * @see com.br.cashflowdao.hibernate.dao.factory.DAOFactory.getTransferTransactionDAO()
     */
    @Override
    public TransferTransactionDAO getTransferTransactionDAO() {
       return (TransferTransactionDAO) instantiateDAO(TransferTransactionDAO.class);
    }

    /**
     * @see com.br.cashflowdao.hibernate.dao.factory.DAOFactory.getTransferTransactionDAO()
     */
    @Override
    public CategoryTypeDAO getCategoryTypeDAO() {
       return (CategoryTypeDAO) instantiateDAO(CategoryTypeDAO.class);
    }
}